home *** CD-ROM | disk | FTP | other *** search
/ Cream of the Crop 26 / Cream of the Crop 26.iso / os2 / octa209s.zip / octave-2.09 / src / data.cc < prev    next >
C/C++ Source or Header  |  1997-03-07  |  22KB  |  1,178 lines

  1. /*
  2.  
  3. Copyright (C) 1996 John W. Eaton
  4.  
  5. This file is part of Octave.
  6.  
  7. Octave is free software; you can redistribute it and/or modify it
  8. under the terms of the GNU General Public License as published by the
  9. Free Software Foundation; either version 2, or (at your option) any
  10. later version.
  11.  
  12. Octave is distributed in the hope that it will be useful, but WITHOUT
  13. ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  14. FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  15. for more details.
  16.  
  17. You should have received a copy of the GNU General Public License
  18. along with Octave; see the file COPYING.  If not, write to the Free
  19. Software Foundation, 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
  20.  
  21. */
  22.  
  23. /*
  24.  
  25. The function builtin_pwd adapted from a similar function from GNU
  26. Bash, the Bourne Again SHell, copyright (C) 1987, 1989, 1991 Free
  27. Software Foundation, Inc.
  28.  
  29. */
  30.  
  31. #ifdef HAVE_CONFIG_H
  32. #include <config.h>
  33. #endif
  34.  
  35. #include <cfloat>
  36. #include <cmath>
  37.  
  38. #include <string>
  39.  
  40. #include "lo-ieee.h"
  41. #include "str-vec.h"
  42.  
  43. #include "defun.h"
  44. #include "error.h"
  45. #include "gripes.h"
  46. #include "help.h"
  47. #include "oct-map.h"
  48. #include "ov.h"
  49. #include "variables.h"
  50. #include "oct-obj.h"
  51. #include "utils.h"
  52.  
  53. #ifndef MIN
  54. #define MIN(a,b) ((a) < (b) ? (a) : (b))
  55. #endif
  56.  
  57. #ifndef ABS
  58. #define ABS(x) (((x) < 0) ? (-x) : (x))
  59. #endif
  60.  
  61. // Should expressions like ones (-1, 5) result in an empty matrix or
  62. // an error?  A positive value means yes.  A negative value means
  63. // yes, but print a warning message.  Zero means it should be
  64. // considered an error.
  65. static int Vtreat_neg_dim_as_zero;
  66.  
  67. DEFUN (all, args, ,
  68.   "all (X): are all elements of X nonzero?")
  69. {
  70.   octave_value_list retval;
  71.  
  72.   int nargin = args.length ();
  73.  
  74.   if (nargin == 1 && args(0).is_defined ())
  75.     retval = args(0).all ();
  76.   else
  77.     print_usage ("all");
  78.  
  79.   return retval;
  80. }
  81.  
  82. DEFUN (any, args, ,
  83.   "any (X): are any elements of X nonzero?")
  84. {
  85.   octave_value_list retval;
  86.  
  87.   int nargin = args.length ();
  88.  
  89.   if (nargin == 1 && args(0).is_defined ())
  90.     retval = args(0).any ();
  91.   else
  92.     print_usage ("any");
  93.  
  94.   return retval;
  95. }
  96.  
  97. // These mapping functions may also be useful in other places, eh?
  98.  
  99. typedef double (*d_dd_fcn) (double, double);
  100.  
  101. static Matrix
  102. map_d_m (d_dd_fcn f, double x, const Matrix& y)
  103. {
  104.   int nr = y.rows ();
  105.   int nc = y.columns ();
  106.  
  107.   Matrix retval (nr, nc);
  108.  
  109.   for (int j = 0; j < nc; j++)
  110.     for (int i = 0; i < nr; i++)
  111.       retval (i, j) = f (x, y (i, j));
  112.  
  113.   return retval;
  114. }
  115.  
  116. static Matrix
  117. map_m_d (d_dd_fcn f, const Matrix& x, double y)
  118. {
  119.   int nr = x.rows ();
  120.   int nc = x.columns ();
  121.  
  122.   Matrix retval (nr, nc);
  123.  
  124.   for (int j = 0; j < nc; j++)
  125.     for (int i = 0; i < nr; i++)
  126.       retval (i, j) = f (x (i, j), y);
  127.  
  128.   return retval;
  129. }
  130.  
  131. static Matrix
  132. map_m_m (d_dd_fcn f, const Matrix& x, const Matrix& y)
  133. {
  134.   int x_nr = x.rows ();
  135.   int x_nc = x.columns ();
  136.  
  137.   int y_nr = y.rows ();
  138.   int y_nc = y.columns ();
  139.  
  140.   assert (x_nr == y_nr && x_nc == y_nc);
  141.  
  142.   Matrix retval (x_nr, x_nc);
  143.  
  144.   for (int j = 0; j < x_nc; j++)
  145.     for (int i = 0; i < x_nr; i++)
  146.       retval (i, j) = f (x (i, j), y (i, j));
  147.  
  148.   return retval;
  149. }
  150.  
  151. DEFUN (atan2, args, ,
  152.   "atan2 (Y, X): atan (Y / X) in range -pi to pi")
  153. {
  154.   octave_value_list retval;
  155.  
  156.   int nargin = args.length ();
  157.  
  158.   if (nargin == 2 && args(0).is_defined () && args(1).is_defined ())
  159.     {
  160.       octave_value arg_y = args(0);
  161.       octave_value arg_x = args(1);
  162.  
  163.       int y_nr = arg_y.rows ();
  164.       int y_nc = arg_y.columns ();
  165.  
  166.       int x_nr = arg_x.rows ();
  167.       int x_nc = arg_x.columns ();
  168.  
  169.       int arg_y_empty = empty_arg ("atan2", y_nr, y_nc);
  170.       int arg_x_empty = empty_arg ("atan2", x_nr, x_nc);
  171.  
  172.       if (arg_y_empty > 0 && arg_x_empty > 0)
  173.     return Matrix ();
  174.       else if (arg_y_empty || arg_x_empty)
  175.     return retval;
  176.  
  177.       int y_is_scalar = (y_nr == 1 && y_nc == 1);
  178.       int x_is_scalar = (x_nr == 1 && x_nc == 1);
  179.  
  180.       if (y_is_scalar && x_is_scalar)
  181.     {
  182.       double y = arg_y.double_value ();
  183.  
  184.       if (! error_state)
  185.         {
  186.           double x = arg_x.double_value ();
  187.  
  188.           if (! error_state)
  189.         retval = atan2 (y, x);
  190.         }
  191.     }
  192.       else if (y_is_scalar)
  193.     {
  194.       double y = arg_y.double_value ();
  195.  
  196.       if (! error_state)
  197.         {
  198.           Matrix x = arg_x.matrix_value ();
  199.  
  200.           if (! error_state)
  201.         retval = map_d_m (atan2, y, x);
  202.         }
  203.     }
  204.       else if (x_is_scalar)
  205.     {
  206.       Matrix y = arg_y.matrix_value ();
  207.  
  208.       if (! error_state)
  209.         {
  210.           double x = arg_x.double_value ();
  211.  
  212.           if (! error_state)
  213.         retval = map_m_d (atan2, y, x);
  214.         }
  215.     }
  216.       else if (y_nr == x_nr && y_nc == x_nc)
  217.     {
  218.       Matrix y = arg_y.matrix_value ();
  219.  
  220.       if (! error_state)
  221.         {
  222.           Matrix x = arg_x.matrix_value ();
  223.  
  224.           if (! error_state)
  225.         retval = map_m_m (atan2, y, x);
  226.         }
  227.     }
  228.       else
  229.     error ("atan2: nonconformant matrices");
  230.     }
  231.   else
  232.     print_usage ("atan2");
  233.  
  234.   return retval;
  235. }
  236.  
  237. DEFUN (cumprod, args, ,
  238.   "cumprod (X): cumulative products")
  239. {
  240.   octave_value_list retval;
  241.  
  242.   int nargin = args.length ();
  243.  
  244.   if (nargin == 1)
  245.     {
  246.       octave_value arg = args(0);
  247.  
  248.       if (arg.is_real_type ())
  249.     {
  250.       Matrix tmp = arg.matrix_value ();
  251.  
  252.       if (! error_state)
  253.         retval(0) = tmp.cumprod ();
  254.     }
  255.       else if (arg.is_complex_type ())
  256.     {
  257.       ComplexMatrix tmp = arg.complex_matrix_value ();
  258.  
  259.       if (! error_state)
  260.         retval(0) = tmp.cumprod ();
  261.     }
  262.       else
  263.     {
  264.       gripe_wrong_type_arg ("cumprod", arg);
  265.       return retval;
  266.     }
  267.     }
  268.   else
  269.     print_usage ("cumprod");
  270.  
  271.   return retval;
  272. }
  273.  
  274. DEFUN (cumsum, args, ,
  275.   "cumsum (X): cumulative sums")
  276. {
  277.   octave_value_list retval;
  278.  
  279.   int nargin = args.length ();
  280.  
  281.   if (nargin == 1)
  282.     {
  283.       octave_value arg = args(0);
  284.  
  285.       if (arg.is_real_type ())
  286.     {
  287.       Matrix tmp = arg.matrix_value ();
  288.  
  289.       if (! error_state)
  290.         retval(0) = tmp.cumsum ();
  291.     }
  292.       else if (arg.is_complex_type ())
  293.     {
  294.       ComplexMatrix tmp = arg.complex_matrix_value ();
  295.  
  296.       if (! error_state)
  297.         retval(0) = tmp.cumsum ();
  298.     }
  299.       else
  300.     {
  301.       gripe_wrong_type_arg ("cumsum", arg);
  302.       return retval;
  303.     }
  304.     }
  305.   else
  306.     print_usage ("cumsum");
  307.  
  308.   return retval;
  309. }
  310.  
  311. static octave_value
  312. make_diag (const Matrix& v, int k)
  313. {
  314.   int nr = v.rows ();
  315.   int nc = v.columns ();
  316.   assert (nc == 1 || nr == 1);
  317.  
  318.   octave_value retval;
  319.  
  320.   int roff = 0;
  321.   int coff = 0;
  322.   if (k > 0)
  323.     {
  324.       roff = 0;
  325.       coff = k;
  326.     }
  327.   else if (k < 0)
  328.     {
  329.       roff = -k;
  330.       coff = 0;
  331.     }
  332.  
  333.   if (nr == 1)
  334.     {
  335.       int n = nc + ABS (k);
  336.       Matrix m (n, n, 0.0);
  337.       for (int i = 0; i < nc; i++)
  338.     m (i+roff, i+coff) = v (0, i);
  339.       retval = octave_value (m);
  340.     }
  341.   else
  342.     {
  343.       int n = nr + ABS (k);
  344.       Matrix m (n, n, 0.0);
  345.       for (int i = 0; i < nr; i++)
  346.     m (i+roff, i+coff) = v (i, 0);
  347.       retval = octave_value (m);
  348.     }
  349.  
  350.   return retval;
  351. }
  352.  
  353. static octave_value
  354. make_diag (const ComplexMatrix& v, int k)
  355. {
  356.   int nr = v.rows ();
  357.   int nc = v.columns ();
  358.   assert (nc == 1 || nr == 1);
  359.  
  360.   octave_value retval;
  361.  
  362.   int roff = 0;
  363.   int coff = 0;
  364.   if (k > 0)
  365.     {
  366.       roff = 0;
  367.       coff = k;
  368.     }
  369.   else if (k < 0)
  370.     {
  371.       roff = -k;
  372.       coff = 0;
  373.     }
  374.  
  375.   if (nr == 1)
  376.     {
  377.       int n = nc + ABS (k);
  378.       ComplexMatrix m (n, n, 0.0);
  379.       for (int i = 0; i < nc; i++)
  380.     m (i+roff, i+coff) = v (0, i);
  381.       retval = octave_value (m);
  382.     }
  383.   else
  384.     {
  385.       int n = nr + ABS (k);
  386.       ComplexMatrix m (n, n, 0.0);
  387.       for (int i = 0; i < nr; i++)
  388.     m (i+roff, i+coff) = v (i, 0);
  389.       retval = octave_value (m);
  390.     }
  391.  
  392.   return retval;
  393. }
  394.  
  395. static octave_value
  396. make_diag (const octave_value& arg)
  397. {
  398.   octave_value retval;
  399.  
  400.   if (arg.is_real_type ())
  401.     {
  402.       Matrix m = arg.matrix_value ();
  403.  
  404.       if (! error_state)
  405.     {
  406.       int nr = m.rows ();
  407.       int nc = m.columns ();
  408.  
  409.       if (nr == 0 || nc == 0)
  410.         retval = Matrix ();
  411.       else if (nr == 1 || nc == 1)
  412.         retval = make_diag (m, 0);
  413.       else
  414.         {
  415.           ColumnVector v = m.diag ();
  416.           if (v.capacity () > 0)
  417.         retval = v;
  418.         }
  419.     }
  420.       else
  421.     gripe_wrong_type_arg ("diag", arg);
  422.     }
  423.   else if (arg.is_complex_type ())
  424.     {
  425.       ComplexMatrix cm = arg.complex_matrix_value ();
  426.  
  427.       if (! error_state)
  428.     {
  429.       int nr = cm.rows ();
  430.       int nc = cm.columns ();
  431.  
  432.       if (nr == 0 || nc == 0)
  433.         retval = Matrix ();
  434.       else if (nr == 1 || nc == 1)
  435.         retval = make_diag (cm, 0);
  436.       else
  437.         {
  438.           ComplexColumnVector v = cm.diag ();
  439.           if (v.capacity () > 0)
  440.         retval = v;
  441.         }
  442.     }
  443.       else
  444.     gripe_wrong_type_arg ("diag", arg);
  445.     }
  446.   else
  447.     gripe_wrong_type_arg ("diag", arg);
  448.  
  449.   return retval;
  450. }
  451.  
  452. static octave_value
  453. make_diag (const octave_value& a, const octave_value& b)
  454. {
  455.   octave_value retval;
  456.  
  457.   double tmp = b.double_value ();
  458.  
  459.   if (error_state)
  460.     {
  461.       error ("diag: invalid second argument");      
  462.       return retval;
  463.     }
  464.  
  465.   int k = NINT (tmp);
  466.   int n = ABS (k) + 1;
  467.  
  468.   if (a.is_real_type ())
  469.     {
  470.       if (a.is_scalar_type ())
  471.     {
  472.       double d = a.double_value ();
  473.  
  474.       if (k == 0)
  475.         retval = d;
  476.       else if (k > 0)
  477.         {
  478.           Matrix m (n, n, 0.0);
  479.           m (0, k) = d;
  480.           retval = m;
  481.         }
  482.       else if (k < 0)
  483.         {
  484.           Matrix m (n, n, 0.0);
  485.           m (-k, 0) = d;
  486.           retval = m;
  487.         }
  488.     }
  489.       else if (a.is_matrix_type ())
  490.     {
  491.       Matrix m = a.matrix_value ();
  492.  
  493.       int nr = m.rows ();
  494.       int nc = m.columns ();
  495.  
  496.       if (nr == 0 || nc == 0)
  497.         retval = Matrix ();
  498.       else if (nr == 1 || nc == 1)
  499.         retval = make_diag (m, k);
  500.       else
  501.         {
  502.           ColumnVector d = m.diag (k);
  503.           retval = d;
  504.         }
  505.     }
  506.       else
  507.     gripe_wrong_type_arg ("diag", a);
  508.     }
  509.   else if (a.is_complex_type ())
  510.     {
  511.       if (a.is_scalar_type ())
  512.     {
  513.       Complex c = a.complex_value ();
  514.  
  515.       if (k == 0)
  516.         retval = c;
  517.       else if (k > 0)
  518.         {
  519.           ComplexMatrix m (n, n, 0.0);
  520.           m (0, k) = c;
  521.           retval = m;
  522.         }
  523.       else if (k < 0)
  524.         {
  525.           ComplexMatrix m (n, n, 0.0);
  526.           m (-k, 0) = c;
  527.           retval = m;
  528.         }
  529.     }
  530.       else if (a.is_matrix_type ())
  531.     {
  532.       ComplexMatrix cm = a.complex_matrix_value ();
  533.  
  534.       int nr = cm.rows ();
  535.       int nc = cm.columns ();
  536.  
  537.       if (nr == 0 || nc == 0)
  538.         retval = Matrix ();
  539.       else if (nr == 1 || nc == 1)
  540.         retval = make_diag (cm, k);
  541.       else
  542.         {
  543.           ComplexColumnVector d = cm.diag (k);
  544.           retval = d;
  545.         }
  546.     }
  547.       else
  548.     gripe_wrong_type_arg ("diag", a);
  549.     }
  550.   else
  551.     gripe_wrong_type_arg ("diag", a);
  552.  
  553.   return retval;
  554. }
  555.  
  556. DEFUN (diag, args, ,
  557.   "diag (X [,k]): form/extract diagonals")
  558. {
  559.   octave_value_list retval;
  560.  
  561.   int nargin = args.length ();
  562.  
  563.   if (nargin == 1 && args(0).is_defined ())
  564.     retval = make_diag (args(0));
  565.   else if (nargin == 2 && args(0).is_defined () && args(1).is_defined ())
  566.     retval = make_diag (args(0), args(1));
  567.   else
  568.     print_usage ("diag");
  569.  
  570.   return retval;
  571. }
  572.  
  573. DEFUN (prod, args, ,
  574.   "prod (X): products")
  575. {
  576.   octave_value_list retval;
  577.  
  578.   int nargin = args.length ();
  579.  
  580.   if (nargin == 1)
  581.     {
  582.       octave_value arg = args(0);
  583.  
  584.       if (arg.is_real_type ())
  585.     {
  586.       Matrix tmp = arg.matrix_value ();
  587.  
  588.       if (! error_state)
  589.         retval(0) = tmp.prod ();
  590.     }
  591.       else if (arg.is_complex_type ())
  592.     {
  593.       ComplexMatrix tmp = arg.complex_matrix_value ();
  594.  
  595.       if (! error_state)
  596.         retval(0) = tmp.prod ();
  597.     }
  598.       else
  599.     {
  600.       gripe_wrong_type_arg ("prod", arg);
  601.       return retval;
  602.     }
  603.     }
  604.   else
  605.     print_usage ("prod");
  606.  
  607.   return retval;
  608. }
  609.  
  610. DEFUN (size, args, nargout,
  611.   "[m, n] = size (x): return rows and columns of X\n\
  612. \n\
  613. d = size (x): return number of rows and columns of x as a row vector\n\
  614. \n\
  615. m = size (x, 1): return number of rows in x\n\
  616. m = size (x, 2): return number of columns in x")
  617. {
  618.   octave_value_list retval;
  619.  
  620.   int nargin = args.length ();
  621.  
  622.   if (nargin == 1 && nargout < 3)
  623.     {
  624.       int nr = args(0).rows ();
  625.       int nc = args(0).columns ();
  626.  
  627.       if (nargout == 0 || nargout == 1)
  628.     {
  629.       Matrix m (1, 2);
  630.       m (0, 0) = nr;
  631.       m (0, 1) = nc;
  632.       retval = m;
  633.     }
  634.       else if (nargout == 2)
  635.     {
  636.       retval(1) = (double) nc;
  637.       retval(0) = (double) nr;
  638.     }
  639.     }
  640.   else if (nargin == 2 && nargout < 2)
  641.     {
  642.       int nd = NINT (args(1).double_value ());
  643.  
  644.       if (error_state)
  645.     error ("size: expecting scalar as second argument");
  646.       else
  647.     {
  648.       if (nd == 1)
  649.         retval(0) = (double) (args(0).rows ());
  650.       else if (nd == 2)
  651.         retval(0) = (double) (args(0).columns ());
  652.       else
  653.         error ("size: invalid second argument -- expecting 1 or 2");
  654.     }
  655.     }
  656.   else
  657.     print_usage ("size");
  658.  
  659.   return retval;
  660. }
  661.  
  662. DEFUN (sum, args, ,
  663.   "sum (X): sum of elements")
  664. {
  665.   octave_value_list retval;
  666.  
  667.   int nargin = args.length ();
  668.  
  669.   if (nargin == 1)
  670.     {
  671.       octave_value arg = args(0);
  672.  
  673.       if (arg.is_real_type ())
  674.     {
  675.       Matrix tmp = arg.matrix_value ();
  676.  
  677.       if (! error_state)
  678.         retval(0) = tmp.sum ();
  679.     }
  680.       else if (arg.is_complex_type ())
  681.     {
  682.       ComplexMatrix tmp = arg.complex_matrix_value ();
  683.  
  684.       if (! error_state)
  685.         retval(0) = tmp.sum ();
  686.     }
  687.       else
  688.     {
  689.       gripe_wrong_type_arg ("sum", arg);
  690.       return retval;
  691.     }
  692.     }
  693.   else
  694.     print_usage ("sum");
  695.  
  696.   return retval;
  697. }
  698.  
  699. DEFUN (sumsq, args, ,
  700.   "sumsq (X): sum of squares of elements")
  701. {
  702.   octave_value_list retval;
  703.  
  704.   int nargin = args.length ();
  705.  
  706.   if (nargin == 1)
  707.     {
  708.       octave_value arg = args(0);
  709.  
  710.       if (arg.is_real_type ())
  711.     {
  712.       Matrix tmp = arg.matrix_value ();
  713.  
  714.       if (! error_state)
  715.         retval(0) = tmp.sumsq ();
  716.     }
  717.       else if (arg.is_complex_type ())
  718.     {
  719.       ComplexMatrix tmp = arg.complex_matrix_value ();
  720.  
  721.       if (! error_state)
  722.         retval(0) = tmp.sumsq ();
  723.     }
  724.       else
  725.     {
  726.       gripe_wrong_type_arg ("sumsq", arg);
  727.       return retval;
  728.     }
  729.     }
  730.   else
  731.     print_usage ("sumsq");
  732.  
  733.   return retval;
  734. }
  735.  
  736. DEFUN (is_struct, args, ,
  737.   "is_struct (x): return nonzero if x is a structure")
  738. {
  739.   octave_value_list retval;
  740.  
  741.   int nargin = args.length ();
  742.  
  743.   if (nargin == 1)
  744.     {
  745.       octave_value arg = args(0);
  746.  
  747.       if (arg.is_map ())
  748.     retval = 1.0;
  749.       else
  750.     retval = 0.0;
  751.     }
  752.   else
  753.     print_usage ("is_struct");
  754.  
  755.   return retval;
  756. }
  757.  
  758. DEFUN (struct_elements, args, ,
  759.   "struct_elements (S)\n\
  760. \n\
  761. Return a list of the names of the elements of the structure S.")
  762. {
  763.   octave_value_list retval;
  764.  
  765.   int nargin = args.length ();
  766.  
  767.   if (nargin == 1)
  768.     {
  769.       if (args (0).is_map ())
  770.     {
  771.       Octave_map m = args(0).map_value ();
  772.       retval(0) = m.make_name_list ();
  773.     }
  774.       else
  775.     gripe_wrong_type_arg ("struct_elements", args (0));
  776.     }
  777.   else
  778.     print_usage ("struct_elements");
  779.  
  780.   return retval;
  781. }
  782.  
  783. DEFUN (struct_contains, args, ,
  784.   "struct_contains (S, NAME)\n\
  785. \n\
  786. Return nonzero if S is a structure with element NAME.\n\
  787. S must be a structure and NAME must be a string.")
  788. {
  789.   octave_value_list retval;
  790.  
  791.   int nargin = args.length ();
  792.  
  793.   if (nargin == 2)
  794.     {
  795.       retval = 0.0;
  796.  
  797.       if (args(0).is_map () && args(1).is_string ())
  798.     {
  799.       string s = args(1).string_value ();
  800.       octave_value tmp = args(0).struct_elt_val (s, true);
  801.       retval = (double) tmp.is_defined ();
  802.     }
  803.       else
  804.     print_usage ("struct_contains");
  805.     }
  806.   else
  807.     print_usage ("struct_contains");
  808.  
  809.   return retval;
  810. }
  811.  
  812. static void
  813. check_dimensions (int& nr, int& nc, const char *warnfor)
  814. {
  815.   if (nr < 0 || nc < 0)
  816.     {
  817.       if (Vtreat_neg_dim_as_zero)
  818.     {
  819.       nr = (nr < 0) ? 0 : nr;
  820.       nc = (nc < 0) ? 0 : nc;
  821.  
  822.       if (Vtreat_neg_dim_as_zero < 0)
  823.         warning ("%s: converting negative dimension to zero",
  824.              warnfor);
  825.     }
  826.       else
  827.     error ("%s: can't create a matrix with negative dimensions",
  828.            warnfor);
  829.     }
  830. }
  831.  
  832. static void
  833. get_dimensions (const octave_value& a, const char *warn_for,
  834.         int& nr, int& nc)
  835. {
  836.   if (a.is_scalar_type ())
  837.     {
  838.       double tmp = a.double_value ();
  839.       nr = nc = NINT (tmp);
  840.     }
  841.   else
  842.     {
  843.       nr = a.rows ();
  844.       nc = a.columns ();
  845.  
  846.       if ((nr == 1 && nc == 2) || (nr == 2 && nc == 1))
  847.     {
  848.       ColumnVector v = a.vector_value ();
  849.  
  850.       if (error_state)
  851.         return;
  852.  
  853.       nr = NINT (v (0));
  854.       nc = NINT (v (1));
  855.     }
  856.       else
  857.     warning ("%s (A): use %s (size (A)) instead", warn_for, warn_for);
  858.     }
  859.  
  860.   check_dimensions (nr, nc, warn_for); // May set error_state.
  861. }
  862.  
  863. static void
  864. get_dimensions (const octave_value& a, const octave_value& b,
  865.         const char *warn_for, int& nr, int& nc)
  866. {
  867.   nr = NINT (a.double_value ());
  868.   nc = NINT (b.double_value ());
  869.  
  870.   if (error_state)
  871.     error ("%s: expecting two scalar arguments", warn_for);
  872.   else
  873.     check_dimensions (nr, nc, warn_for); // May set error_state.
  874. }
  875.  
  876. static octave_value
  877. fill_matrix (const octave_value& a, double val, const char *warn_for)
  878. {
  879.   int nr, nc;
  880.   get_dimensions (a, warn_for, nr, nc);
  881.  
  882.   if (error_state)
  883.     return  octave_value ();
  884.  
  885.   Matrix m (nr, nc, val);
  886.  
  887.   return m;
  888. }
  889.  
  890. static octave_value
  891. fill_matrix (const octave_value& a, const octave_value& b,
  892.          double val, const char *warn_for)
  893. {
  894.   int nr, nc;
  895.   get_dimensions (a, b, warn_for, nr, nc); // May set error_state.
  896.  
  897.   if (error_state)
  898.     return octave_value ();
  899.  
  900.   Matrix m (nr, nc, val);
  901.  
  902.   return m;
  903. }
  904.  
  905. DEFUN (ones, args, ,
  906.   "ones (N), ones (N, M), ones (X): create a matrix of all ones")
  907. {
  908.   octave_value_list retval;
  909.  
  910.   int nargin = args.length ();
  911.  
  912.   switch (nargin)
  913.     {
  914.     case 0:
  915.       retval = 1.0;
  916.       break;
  917.  
  918.     case 1:
  919.       retval = fill_matrix (args(0), 1.0, "ones");
  920.       break;
  921.  
  922.     case 2:
  923.       retval = fill_matrix (args(0), args(1), 1.0, "ones");
  924.       break;
  925.  
  926.     default:
  927.       print_usage ("ones");
  928.       break;
  929.     }
  930.  
  931.   return retval;
  932. }
  933.  
  934. DEFUN (zeros, args, ,
  935.   "zeros (N), zeros (N, M), zeros (X): create a matrix of all zeros")
  936. {
  937.   octave_value_list retval;
  938.  
  939.   int nargin = args.length ();
  940.  
  941.   switch (nargin)
  942.     {
  943.     case 0:
  944.       retval = 0.0;
  945.       break;
  946.  
  947.     case 1:
  948.       retval = fill_matrix (args(0), 0.0, "zeros");
  949.       break;
  950.  
  951.     case 2:
  952.       retval = fill_matrix (args(0), args(1), 0.0, "zeros");
  953.       break;
  954.  
  955.     default:
  956.       print_usage ("zeros");
  957.       break;
  958.     }
  959.  
  960.   return retval;
  961. }
  962.  
  963. static octave_value
  964. identity_matrix (const octave_value& a)
  965. {
  966.   int nr, nc;
  967.   get_dimensions (a, "eye", nr, nc); // May set error_state.
  968.  
  969.   if (error_state)
  970.     return octave_value ();
  971.  
  972.   Matrix m (nr, nc, 0.0);
  973.  
  974.   if (nr > 0 && nc > 0)
  975.     {
  976.       int n = MIN (nr, nc);
  977.       for (int i = 0; i < n; i++)
  978.     m (i, i) = 1.0;
  979.     }
  980.  
  981.   return m;
  982. }
  983.  
  984. static octave_value
  985. identity_matrix (const octave_value& a, const octave_value& b)
  986. {
  987.   int nr, nc;
  988.   get_dimensions (a, b, "eye", nr, nc);  // May set error_state.
  989.  
  990.   if (error_state)
  991.     return octave_value ();
  992.  
  993.   Matrix m (nr, nc, 0.0);
  994.  
  995.   if (nr > 0 && nc > 0)
  996.     {
  997.       int n = MIN (nr, nc);
  998.       for (int i = 0; i < n; i++)
  999.     m (i, i) = 1.0;
  1000.     }
  1001.  
  1002.   return m;
  1003. }
  1004.  
  1005. DEFUN (eye, args, ,
  1006.   "eye (N), eye (N, M), eye (X): create an identity matrix")
  1007. {
  1008.   octave_value_list retval;
  1009.  
  1010.   int nargin = args.length ();
  1011.  
  1012.   switch (nargin)
  1013.     {
  1014.     case 0:
  1015.       retval = 1.0;
  1016.       break;
  1017.  
  1018.     case 1:
  1019.       retval = identity_matrix (args(0));
  1020.       break;
  1021.  
  1022.     case 2:
  1023.       retval = identity_matrix (args(0), args(1));
  1024.       break;
  1025.  
  1026.     default:
  1027.       print_usage ("eye");
  1028.       break;
  1029.     }
  1030.  
  1031.   return retval;
  1032. }
  1033.  
  1034. DEFUN (linspace, args, ,
  1035.   "usage: linspace (x1, x2, n)\n\
  1036. \n\
  1037. Return a vector of n equally spaced points between x1 and x2\n\
  1038. inclusive.\n\
  1039. \n\
  1040. If the final argument is omitted, n = 100 is assumed.\n\
  1041. \n\
  1042. All three arguments must be scalars.\n\
  1043. \n\
  1044. See also: logspace")
  1045. {
  1046.   octave_value_list retval;
  1047.  
  1048.   int nargin = args.length ();
  1049.  
  1050.   int npoints = 100;
  1051.  
  1052.   if (nargin != 2 && nargin != 3)
  1053.     {
  1054.       print_usage ("linspace");
  1055.       return retval;
  1056.     }
  1057.  
  1058.   if (nargin == 3)
  1059.     {
  1060.       double n = args(2).double_value ();
  1061.  
  1062.       if (! error_state)
  1063.     npoints = NINT (n);
  1064.     }
  1065.  
  1066.   if (! error_state)
  1067.     {
  1068.       if (npoints > 1)
  1069.     {
  1070.       octave_value arg_1 = args(0);
  1071.       octave_value arg_2 = args(1);
  1072.  
  1073.       if (arg_1.is_complex_type () || arg_2.is_complex_type ())
  1074.         {
  1075.           Complex x1 = arg_1.complex_value ();
  1076.           Complex x2 = arg_2.complex_value ();
  1077.  
  1078.           if (! error_state)
  1079.         {
  1080.           ComplexRowVector rv = linspace (x1, x2, npoints);
  1081.  
  1082.           if (! error_state)
  1083.             retval (0) = octave_value (rv, 0);
  1084.         }
  1085.         }
  1086.       else
  1087.         {
  1088.           double x1 = arg_1.double_value ();
  1089.           double x2 = arg_2.double_value ();
  1090.  
  1091.           if (! error_state)
  1092.         {
  1093.           RowVector rv = linspace (x1, x2, npoints);
  1094.  
  1095.           if (! error_state)
  1096.             retval (0) = octave_value (rv, 0);
  1097.         }
  1098.         }
  1099.     }
  1100.       else
  1101.     error ("linspace: npoints must be greater than 2");
  1102.     }
  1103.  
  1104.   return retval;
  1105. }
  1106.  
  1107. static int
  1108. treat_neg_dim_as_zero (void)
  1109. {
  1110.   Vtreat_neg_dim_as_zero = check_preference ("treat_neg_dim_as_zero");
  1111.  
  1112.   return 0;
  1113. }
  1114.  
  1115. void
  1116. symbols_of_data (void)
  1117. {
  1118.   DEFCONST (I, Complex (0.0, 1.0), 0, 0,
  1119.     "sqrt (-1)");
  1120.  
  1121.   DEFCONST (Inf, octave_Inf, 0, 0,
  1122.     "infinity");
  1123.  
  1124.   DEFCONST (J, Complex (0.0, 1.0), 0, 0,
  1125.     "sqrt (-1)");
  1126.  
  1127.   DEFCONST (NaN, octave_NaN, 0, 0,
  1128.     "not a number");
  1129.  
  1130. #if defined (M_E)
  1131.   double e_val = M_E;
  1132. #else
  1133.   double e_val = exp (1.0);
  1134. #endif
  1135.  
  1136.   DEFCONST (e, e_val, 0, 0,
  1137.     "exp (1)");
  1138.  
  1139.   DEFCONST (eps, DBL_EPSILON, 0, 0,
  1140.     "machine precision");
  1141.  
  1142.   DEFCONST (i, Complex (0.0, 1.0), 1, 0,
  1143.     "sqrt (-1)");
  1144.  
  1145.   DEFCONST (inf, octave_Inf, 0, 0,
  1146.     "infinity");
  1147.  
  1148.   DEFCONST (j, Complex (0.0, 1.0), 1, 0,
  1149.     "sqrt (-1)");
  1150.  
  1151.   DEFCONST (nan, octave_NaN, 0, 0,
  1152.     "not a number");
  1153.  
  1154. #if defined (M_PI)
  1155.   double pi_val = M_PI;
  1156. #else
  1157.   double pi_val = 4.0 * atan (1.0);
  1158. #endif
  1159.  
  1160.   DEFCONST (pi, pi_val, 0, 0,
  1161.     "ratio of the circumference of a circle to its diameter");
  1162.  
  1163.   DEFCONST (realmax, DBL_MAX, 0, 0,
  1164.     "realmax (): return largest representable floating point number");
  1165.  
  1166.   DEFCONST (realmin, DBL_MIN, 0, 0,
  1167.     "realmin (): return smallest representable floating point number");
  1168.  
  1169.   DEFVAR (treat_neg_dim_as_zero, 0.0, 0, treat_neg_dim_as_zero,
  1170.     "convert negative dimensions to zero");
  1171. }
  1172.  
  1173. /*
  1174. ;;; Local Variables: ***
  1175. ;;; mode: C++ ***
  1176. ;;; End: ***
  1177. */
  1178.